package com.zx.callback.service.impl;

import com.alibaba.fastjson.JSON;
import com.zx.callback.common.enums.MessageEnumTable;
import com.zx.callback.common.enums.OrderStateEnum;
import com.zx.callback.common.enums.TradeStateEnum;
import com.zx.callback.common.ex.DaoException;
import com.zx.callback.common.utils.DateUtil;
import com.zx.callback.dao.OrderInfoMapper;
import com.zx.callback.dao.OrderStateInfoMapper;
import com.zx.callback.dao.PayThirdTradeMapper;
import com.zx.callback.po.OrderInfo;
import com.zx.callback.po.OrderStateInfo;
import com.zx.callback.po.PayThirdTrade;
import com.zx.callback.service.CouponInfoService;
import com.zx.callback.service.PayOrderService;
import com.zx.callback.vo.JsonResult;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

/**
 * @author ：yanst
 * @since: 2017/11/22
 * @history：(date editor desc)
 */
@Service
@Transactional
public class PayOrderServiceImpl extends BaseService implements PayOrderService {

    @Resource
    private PayThirdTradeMapper payThirdTradeMapper;

    @Resource
    private OrderInfoMapper orderInfoMapper;

    @Resource
    private OrderStateInfoMapper orderStateInfoMapper;

    @Resource
    private CouponInfoService couponInfoService;

    @Override
    public JsonResult<PayThirdTrade> validNotifyUrlForAlipay(Map<String, String> paramsMap) {
        if (paramsMap == null
                || paramsMap.size() == 0
                || StringUtils.isBlank(paramsMap.get("trade_no"))
                || StringUtils.isBlank(paramsMap.get("out_trade_no"))
                || StringUtils.isBlank(paramsMap.get("app_id"))
                || StringUtils.isBlank(paramsMap.get("trade_status"))
                || StringUtils.isBlank(paramsMap.get("gmt_payment"))
                || StringUtils.isBlank(paramsMap.get("trade_status"))
                || StringUtils.isBlank(paramsMap.get("total_amount"))){
            logger.error("支付同步跳转参数不正确，paramsMap={}", JSON.toJSONString(paramsMap));
            return JsonResult.getJsonObj(MessageEnumTable.PARAM_ERROR);
        }
        //交易号 如：APBTIP2017121110330029
        String tradeNo = paramsMap.get("out_trade_no");
        String totalAmount = paramsMap.get("total_amount");
        PayThirdTrade payThirdTrade = payThirdTradeMapper.getByTradeNo(tradeNo);
        if (payThirdTrade == null){
            logger.error("当前交易订单不存在，paramsMap={}", JSON.toJSONString(paramsMap));
            return JsonResult.getJsonObj(MessageEnumTable.PAY_ORDER_NOT_EXIST);
        }

//        logger.warn("是应该应该交易金额：{}，测试金额：{}", payThirdTrade.getPayAmount(), "0.2");
        if (payThirdTrade.getPayAmount().compareTo(new BigDecimal(totalAmount)) != 0){
            logger.error("实际支付金额与交易金额不等，支付宝返回金额:{}，实际支付金额：{}。", totalAmount, payThirdTrade.getPayAmount());
            return JsonResult.getJsonObj(MessageEnumTable.PAY_ORDER_NOT_EXIST);
        }
        return JsonResult.getOkJsonObj(payThirdTrade);
    }


    @Override
    @Transactional
    public JsonResult<String> updatePayState(OrderInfo orderInfo, PayThirdTrade payThirdTrade, Map<String, String> paramsMap) {
        if (orderInfo == null
                || orderInfo.getId() == null
                || orderInfo.getId().longValue() == 0
                || payThirdTrade.getId() == null
                || payThirdTrade.getId().longValue() == 0) {
            return JsonResult.getJsonObj(MessageEnumTable.PARAM_ERROR);
        }

        /** 修改订单状态 */
        updateOrderState(orderInfo);

        // 支付宝返回的收款金额
        BigDecimal receiptAmount = new BigDecimal(paramsMap.get("receipt_amount"));
        // 支付宝返回的支付时间
        Date payTime = DateUtil.parseDateFromStr(paramsMap.get("gmt_payment"), DateUtil.DATE_FORMATE_LONG);
        // 外部第三方返回的交易流水号
        String outThirdTradeNo = paramsMap.get("trade_no");
        // 第三方交易订单付款成功
        int count = payThirdTradeMapper.updateSuccess(payThirdTrade.getId(), TradeStateEnum.TRADE_SUCCESS.getCode(), payThirdTrade.getTradeState(), receiptAmount, outThirdTradeNo, payTime);
        if (count != 1) {
            logger.error("修改支付第三方交易订单表的状态失败：fail");
            throw new DaoException("修改支付第三方交易订单表的状态失败");
//            return JsonResult.getJsonObj(MessageEnumTable.PAY_UPDATE_PAY_TABLE_STATE_ERROR);
        }
        return JsonResult.getOkJsonObj("success");
    }

    @Transactional
    private void updateOrderState(OrderInfo orderInfo){
        int count = orderInfoMapper.updateOrderStatePaySucessById(orderInfo.getId(),orderInfo.getCouponMoney());
        if (count != 1) {
            logger.error("修改订单状态为已支付失败：fail");
            throw new DaoException("修改订单状态为已支付失败");
        }
        OrderStateInfo stateInfo = new OrderStateInfo();
        stateInfo.setUserId(orderInfo.getUserId());
        stateInfo.setModifyTime(new Date());
        stateInfo.setOrderId(orderInfo.getId());
        stateInfo.setOldState(orderInfo.getState());
        stateInfo.setNowState(OrderStateEnum.ALREADY_PAY.getKey());
        stateInfo.setRemark("把状态："+OrderStateEnum.getNameForKey(orderInfo.getState()).getValue()+"，改为"+(OrderStateEnum.getNameForKey(OrderStateEnum.ALREADY_PAY.getKey()).getValue()));
        count = orderStateInfoMapper.insertSelective(stateInfo);
        if (count != 1){
            throw new RuntimeException("取消订单，修改订单状态表，sql影响行数不匹配。");
        }
    }
}
